"""
钩子中心
实现事件驱动的插件间通信机制
"""

from typing import Any, Callable, Dict, List
import threading


class HookHub:
    """
    钩子中心
    实现事件驱动的插件间通信机制
    """
    
    def __init__(self) -> None:
        self._hooks: Dict[str, List[Callable[..., Any]]] = {}
        self._lock = threading.RLock()
    
    def on(self, event: str, handler: Callable[..., Any]) -> None:
        """
        注册事件处理器
        
        Args:
            event: 事件名称
            handler: 处理器函数
        """
        with self._lock:
            if event not in self._hooks:
                self._hooks[event] = []
            self._hooks[event].append(handler)
    
    def off(self, event: str, handler: Callable[..., Any]) -> None:
        """
        移除事件处理器
        
        Args:
            event: 事件名称
            handler: 处理器函数
        """
        with self._lock:
            if event in self._hooks:
                try:
                    self._hooks[event].remove(handler)
                except ValueError:
                    pass
    
    def emit(self, event: str, *args: Any, **kwargs: Any) -> None:
        """
        触发事件
        
        Args:
            event: 事件名称
            *args: 位置参数
            **kwargs: 关键字参数
        """
        handlers = []
        with self._lock:
            if event in self._hooks:
                handlers = self._hooks[event].copy()
        
        for handler in handlers:
            try:
                handler(*args, **kwargs)
            except Exception as e:
                print(f"Error in hook handler for event '{event}': {e}")
    
    def once(self, event: str, handler: Callable[..., Any]) -> None:
        """
        注册一次性事件处理器（只触发一次）
        
        Args:
            event: 事件名称
            handler: 处理器函数
        """
        def once_handler(*args: Any, **kwargs: Any) -> None:
            try:
                handler(*args, **kwargs)
            finally:
                self.off(event, once_handler)
        
        self.on(event, once_handler)
    
    def get_handlers(self, event: str) -> List[Callable[..., Any]]:
        """
        获取事件的所有处理器
        
        Args:
            event: 事件名称
            
        Returns:
            处理器列表
        """
        with self._lock:
            return self._hooks.get(event, []).copy()